from __future__ import print_function

# from socket import socket
from time import sleep
import RPi.GPIO as GPIO
import numpy as np
import smbus
from distlib.compat import raw_input
from scipy.signal import find_peaks
import signal

I2C_WRITE_ADDR = 0xAE
I2C_READ_ADDR = 0xAF

REG_INIR_STATUS_1 = 0x00
REG_INIR_STATUS_2 = 0x01

REG_INIR_ENABLE_1 = 0x02
REG_INIR_ENABLE_2 = 0x03

REG_FIFO_WR_PTR = 0x04
REG_OVF_COUNTER = 0x05
REG_FIFO_RD_PTR = 0x06
REG_FIFO_DATA = 0x07
REG_FIFO_CONFIG = 0x08

REG_MODE_CONFIG = 0x09
REG_SPO2_CONFIG = 0x0A
REG_LED1_PA = 0x0C

REG_LED2_PA = 0x0D
REG_PILOT_PA = 0x10
REG_MULTI_LED_CTRL1 = 0x11
REG_MULTI_LED_CTRL2 = 0x12

REG_TEMP_INTR = 0x1F
REG_TEMP_FRAC = 0x20
REG_TEMP_CONFIG = 0x21
REG_PROX_INT_THRESH = 0x30
REG_REV_ID = 0xFE
REG_PART_ID = 0xFF

MAX_BRIGHTNESS = 255

# Max30102定义类
class MAX30102():
    def __init__(self, channel=1, address=0X57, gpio_pin=7):
        print("Channel:{0}, address:{1}".format(channel, address))
        self.address = address
        self.channel = channel
        self.bus = smbus.SMBus(self.channel)
        self.interrupt = gpio_pin

        # set gpio mode
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(self.interrupt, GPIO.IN)

        self.reset()

        sleep(1)

        reg_data = self.bus.read_i2c_block_data(self.address, REG_INIR_STATUS_1, 1)
        self.setup()

    def shutdown(self):
        self.bus.write_i2c_block_data(self.address, REG_MODE_CONFIG, [0x80])

    def reset(self):
        self.bus.write_i2c_block_data(self.address, REG_MODE_CONFIG, [0x40])

    def setup(self, led_mode=0x03):
        self.bus.write_i2c_block_data(self.address, REG_INIR_ENABLE_1, [0xc0])
        self.bus.write_i2c_block_data(self.address, REG_INIR_ENABLE_2, [0x00])
        self.bus.write_i2c_block_data(self.address, REG_FIFO_WR_PTR, [0x00])
        self.bus.write_i2c_block_data(self.address, REG_OVF_COUNTER, [0x00])
        self.bus.write_i2c_block_data(self.address, REG_FIFO_RD_PTR, [0x00])

        self.bus.write_i2c_block_data(self.address, REG_FIFO_CONFIG, [0x4f])
        self.bus.write_i2c_block_data(self.address, REG_MODE_CONFIG, [led_mode])
        self.bus.write_i2c_block_data(self.address, REG_SPO2_CONFIG, [0x27])
        self.bus.write_i2c_block_data(self.address, REG_LED1_PA, [0x24])
        self.bus.write_i2c_block_data(self.address, REG_LED2_PA, [0x24])
        self.bus.write_i2c_block_data(self.address, REG_PILOT_PA, [0x7f])

    def set_config(self, reg, value):
        self.bus.write_i2c_block_data(self.address, reg, value)

    def read_fifo(self):
        red_led = []
        ir_led = []

        reg_INTR1 = self.bus.read_i2c_block_data(self.address, REG_INIR_STATUS_1, 1)
        reg_INTR2 = self.bus.read_i2c_block_data(self.address, REG_INIR_STATUS_2, 1)
        d = []
        d = self.bus.read_i2c_block_data(self.address, REG_FIFO_DATA, 6)
        if d is None:
            red_led = None
            ir_led = None
        else:
            red_led = (d[0] << 16 | d[1] << 8 | d[2]) & 0x03FFFF
            ir_led = (d[3] << 16 | d[4] << 8 | d[5]) & 0x03FFFF
        return red_led, ir_led

    def read_sequential(self, amount=100):
        red_buf = []
        ir_buf = []
        Spo2 = []
        num = 0
        for i in range(amount):
            while GPIO.input(self.interrupt) == 1:
                pass
            red, ir = self.read_fifo()
            #
            '''
            ###
            '''
            R = red / (ir+red)
            data = 110 - 25 * R
            num = num+data
            Spo2.append(data)
            red_buf.append(red)
            ir_buf.append(ir)
        return red_buf, ir_buf, Spo2, num


# tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# tcp_client_socket.connect(("434b2006a8.qicp.vip", 49916))

while True:
    c = raw_input()
    if c == "q":
        print("退出...")
        break
    elif c=="w":
        print("检测中...")
        print("请耐心等待30s")
        # 读取血氧初始数据
        m = MAX30102()
        # 获取数据长度
        red, ir, spo2, num= m.read_sequential(1000)

        data_red = red
        data_ir = ir
        data_spo2 = num/len(spo2)
        data_h = np.fft.fft(data_red, n=None, axis=-1, norm=None)
        [pks, locs] = find_peaks(data_h, height=None, threshold=None, distance=5,
                                 prominence=None, width=None, wlen=None, rel_height=None,
                                 plateau_size=None)
        print("心率为:每分钟{}下".format(len(pks) / 2))
        print("血氧浓度为：{}%".format(round(data_spo2,2)))
